#include "Environment.h"

/**
 * Default constructor.
 */
Environment::Environment()
{}

/**
 * Default destructor.
 */
Environment::~Environment()
{
	this->end();
}

/**
 * Initiates the SDL graphics and creates a window.
 *
 * @param screenWidth - intvalue setting windows width.
 * @param screenHight - int value setting window hight.
 * @param windowsTitle - string value setting the window title.
 */
void Environment::init(int screenWidth, int screenHeight,
					   const char *windowTitle)
{
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
	{
		printf("Unable to initialize SDL: %s\n", SDL_GetError());
		this->end();
	}
	
	atexit(SDL_Quit);
	
	mScreen = SDL_SetVideoMode(screenWidth, screenHeight, 24,
							   SDL_DOUBLEBUF | SDL_HWSURFACE);
	if (mScreen == NULL)
	{
		printf("Unable to set video mode: %s\n", SDL_GetError());
		this->end();
	}
	
	SDL_WM_SetCaption(windowTitle, "");
	
	// initialize sdl mixer, open up the audio device
	if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 512) < 0)
		printf("Unable to open SDL_mixer: %s\n", SDL_GetError());
	
	Mix_Music* music;
	
	// load the song
	if(!(music = Mix_LoadMUS("song.mp3")))
		printf("Unable to load song: %s\n", SDL_GetError());
	
	// start playing and displaying the wav
	if(Mix_PlayMusic(music, 1) == -1)
		printf("Unable to play song: %s\n", SDL_GetError());

	this->loadScene();
	
	this->gameLoop();
	
	this->end();
}

/**
 * Quits the SDL.
 */
void Environment::end()
{
	Mix_CloseAudio();
	SDL_Quit();
}

/**
 * Game loop that controls the games functions
 */
void Environment::gameLoop()
{
	int locX = mScreen->w / 2;
	int locY = mScreen->h / 2;
	
	static double lastFrameTime = 0.0;
	static double cyclesLeftOver = 0.0;
	double currentTime;
	double updateIterations;
	
	bool run = true;
	
	while(run)
	{
		currentTime = SDL_GetTicks() * 0.001f;
		updateIterations = ((currentTime - lastFrameTime) + cyclesLeftOver);
		
		if (updateIterations > (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL))
		{
			updateIterations = (MAX_CYCLES_PER_FRAME * UPDATE_INTERVAL);
		}
		
		while (updateIterations > UPDATE_INTERVAL)
		{
			updateIterations -= UPDATE_INTERVAL;
			
			//updateGame(); /* Update game state a variable number of times */
			SDL_Event event;
			SDL_PollEvent( &event );
			
			if( event.type == SDL_QUIT )
			{
				run = false;
				break;
			}
			
			if( event.type == SDL_KEYDOWN )
			{			
				if(event.key.keysym.sym == SDLK_ESCAPE)
				{
					run = false;
					break;
				}
				if(event.key.keysym.sym == SDLK_UP)
					locY = locY - 1;
				if(event.key.keysym.sym == SDLK_DOWN)
					locY = locY + 1;
				if(event.key.keysym.sym == SDLK_LEFT)
					locX = locX - 1;
				if(event.key.keysym.sym == SDLK_RIGHT)
					locX = locX + 1;
				if(event.key.keysym.sym == SDLK_SPACE)
					this->shoot();
			}
		}
		
		cyclesLeftOver = updateIterations;
		lastFrameTime = currentTime;
		
		this->gameAction(locX, locY);
		
		SDL_Delay(16);
	}
}

/**
 * Updates screen content.
 */
void Environment::gameAction(int posX, int posY)
{	
	this->updateBackground();
	
	SDL_Rect src, dest;
	
	src.x = 0;
	src.y = 0;
	src.w = mImage->w;
	src.h = mImage->h;
	
	dest.x = posX;
	dest.y = posY;	
	dest.w = mImage->w;
	dest.h = mImage->h;
	
	SDL_BlitSurface(mImage, &src, mScreen, &dest);
		
	// update the screen buffer
	SDL_Flip(mScreen);
}

/**
 * Loads a image.
 * 
 * @param string containing name of file.
 * @returns an SDL_Surface containing image.
 */
SDL_Surface* Environment::loadImage(std::string imgName)
{
	SDL_Surface *image;
	SDL_Surface *temp;
	
	
	temp = IMG_Load( imgName.c_str() );
	if ( temp == NULL )
	{
		printf( "Unable to load bitmap: %s\n", SDL_GetError() );
		this->end();
	}
	
	image = SDL_DisplayFormatAlpha(temp);
	SDL_FreeSurface(temp);
	
	return image;
}

/**
 * Loads resources used by game.
 */
void Environment::loadScene()
{
	mImage = this->loadImage( "ship.png" );
}

/**
 * Update background.
 */
void Environment::updateBackground()
{
	SDL_FillRect(mScreen, &mScreen->clip_rect,
				 SDL_MapRGB(mScreen->format, 57, 57, 57 ));
	
	SDL_Rect left, right;
	
	left.w = 200;
	left.h = 600;
	left.x = 0;
	left.y = 0;
	
	SDL_FillRect(mScreen, &left, 0);
	
	right.w = 200;
	right.h = 600;
	right.x = 600;
	right.y = 0;
	
	SDL_FillRect(mScreen, &right, 0);
}

/**
 * Shoots a bullit.
 */
void Environment::shoot()
{
	Mix_Chunk* shot;
	int channel = -1;
	
	// load the song
	if(!(shot = Mix_LoadWAV("fire.ogg")))
		printf("Unable to load song: %s\n", SDL_GetError());
	
	// start playing and displaying the wav
	if(channel = Mix_PlayChannel(-1, shot, 0))
		printf("Unable to play song: %s\n", SDL_GetError());
	
	while(Mix_Playing(channel) != 0);
		Mix_FreeChunk(shot);
}	
